ATOM Documentation

← Back to App

Terminal Command Security - Tenant Configuration

Overview

The ATOM SaaS platform provides tenant-configurable terminal command security to ensure safe execution of terminal skills while allowing customization based on tenant needs and plan tiers.

Features

  • **Per-Tenant Configuration**: Each tenant can customize their terminal security settings
  • **Platform Defaults**: Hardcoded fallbacks ensure security even if database config is missing
  • **Tier-Based Permissions**: Higher tiers get additional commands automatically
  • **Security Modes**: Restrictive, permissive, or custom modes
  • **Caching**: In-memory cache with 1-minute TTL for performance
  • **Audit Logging**: All configuration changes logged to audit_logs table

Security Model

Platform Defaults

**Whitelist Commands** (14 commands):

  • ls, pwd, echo, cat, grep, find
  • node, python3, python, npm
  • git, docker, head, tail, wc

**Blacklist Commands** (16 commands):

  • rm, rmdir, mv, cp, chmod, chown
  • dd, mkfs, fdisk, kill, killall
  • sudo, su, nc, netcat, curl, wget

Tier-Based Bonuses

TierBonus CommandsDescription
FreeNonePlatform defaults only
Solocurl, wget, rsync, sshRemoved from blacklist, added to whitelist
Teamcurl, wget, rsync, sshAdditional network tools
EnterpriseNo blacklistCan override platform defaults (blacklist empty)

Security Modes

ModeWhitelist BehaviorBlacklist Behavior
Restrictive**Enforced** - only whitelist commands allowed**Always enforced** - blocked commands always denied
PermissiveNot enforced - any command allowed**Always enforced** - blocked commands always denied
CustomTenant-defined behaviorTenant-defined behavior

API Endpoints

GET /api/admin/terminal-security

Get tenant's current terminal security configuration.

**Required Role**: super_admin, admin, workspace_admin

**Response**:

{
  "tenant_id": "uuid",
  "tier": "team",
  "whitelist": ["ls", "pwd", "echo", "cat", "grep", "find", "node", "python3", "python", "npm", "git", "docker", "head", "tail", "wc"],
  "blacklist": ["rm", "rmdir", "mv", "cp", "chmod", "chown", "dd", "mkfs", "fdisk", "kill", "killall", "sudo", "su", "nc", "netcat", "curl", "wget"],
  "mode": "restrictive",
  "timeout": 30000
}

PATCH /api/admin/terminal-security

Update tenant's terminal security configuration.

**Required Role**: super_admin, admin, workspace_admin

**Request Body**:

{
  "whitelist": ["ls", "pwd", "echo", "cat"],  // Optional: array of command names
  "blacklist": ["rm", "mv", "chmod"],         // Optional: array of command names
  "mode": "permissive",                       // Optional: "restrictive" | "permissive" | "custom"
  "timeout": 60000                            // Optional: 1000-300000ms (5 minutes max)
}

**Validation Rules**:

  • Commands must be alphanumeric (a-z, A-Z, 0-9, -, _)
  • Whitelist cannot be empty in restrictive mode
  • Timeout must be between 1000ms and 300000ms
  • Mode must be one of: restrictive, permissive, custom

**Response**:

{
  "success": true,
  "updated": ["whitelist", "mode"]
}

DELETE /api/admin/terminal-security

Reset tenant's terminal security to platform defaults.

**Required Role**: super_admin only

**Response**:

{
  "success": true,
  "message": "Terminal security settings reset to platform defaults"
}

Usage Examples

Example 1: Get Current Settings

const response = await fetch('/api/admin/terminal-security', {
  method: 'GET',
  headers: {
    'Content-Type': 'application/json'
  }
});

const settings = await response.json();
console.log('Current mode:', settings.mode);
console.log('Allowed commands:', settings.whitelist);

Example 2: Add Command to Whitelist

const response = await fetch('/api/admin/terminal-security', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    whitelist: ['ls', 'pwd', 'echo', 'cat', 'grep', 'find', 'jq'] // Add jq command
  }
});

const result = await response.json();
console.log('Updated:', result.updated);

Example 3: Switch to Permissive Mode

const response = await fetch('/api/admin/terminal-security', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    mode: 'permissive'
  }
});

Example 4: Increase Command Timeout

const response = await fetch('/api/admin/terminal-security', {
  method: 'PATCH',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    timeout: 60000 // 60 seconds
  }
});

Example 5: Reset to Defaults (Super Admin Only)

const response = await fetch('/api/admin/terminal-security', {
  method: 'DELETE'
});

const result = await response.json();
console.log(result.message);

Security Guarantees

Blacklist Always Wins

The blacklist is checked **before** the whitelist in all modes. This ensures dangerous commands are always blocked regardless of mode or tier.

**Exception**: Enterprise tier has no blacklist restrictions.

Platform Defaults Exist

Even if the database is missing or corrupted, hardcoded platform defaults ensure security:

  • Whitelist: 14 safe commands
  • Blacklist: 16 dangerous commands
  • Mode: restrictive
  • Timeout: 30000ms

Audit Trail

All configuration changes are logged to audit_logs table:

  • Who made the change (user_id)
  • What changed (updated fields)
  • When (timestamp)
  • Tenant context

Role-Based Access

  • **View Settings**: super_admin, admin, workspace_admin
  • **Update Settings**: super_admin, admin, workspace_admin
  • **Reset to Defaults**: super_admin only

Database Schema

tenant_settings Table

CREATE TABLE tenant_settings (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    setting_key VARCHAR(255) NOT NULL,
    setting_value TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(tenant_id, setting_key)
);

Setting Keys

KeyTypeExample Value
terminal_command_whitelistJSON["ls","pwd","echo"]
terminal_command_blacklistJSON["rm","mv","chmod"]
terminal_security_modeStringrestrictive
terminal_command_timeout_msInteger30000

Migration

To apply the database migration:

cd backend-saas
alembic upgrade head

This will:

  1. Create tenant_settings table (if not exists)
  2. Populate platform defaults for all existing tenants
  3. Ensure all tenants have terminal security configuration

Testing

Unit Tests

npm test -- terminal-security.test.ts

Integration Tests

npm test -- route.test.ts

E2E Tests

npm run test:e2e

Troubleshooting

Issue: Commands Not Allowed

**Symptom**: Agent fails with "Security Block: Command 'X' is not in the allowed whitelist"

**Solution**:

  1. Check tenant settings: GET /api/admin/terminal-security
  2. Add command to whitelist if appropriate
  3. Or switch to permissive mode (allows all except blacklist)

Issue: Cache Staleness

**Symptom**: Changes to settings not taking effect immediately

**Solution**: Cache automatically invalidates after 1 minute. For immediate effect:

  1. Restart the application server
  2. Or wait 60 seconds for cache expiry

Issue: Migration Fails

**Symptom**: alembic upgrade head fails with "relation does not exist"

**Solution**: Ensure PostgreSQL is running and DATABASE_URL is correctly set in .env:

# Check database connection
psql $DATABASE_URL -c "SELECT 1"

# Run migration
cd backend-saas && alembic upgrade head

Best Practices

  1. **Start Restrictive**: Use restrictive mode for new tenants
  2. **Audit Changes**: Review audit_logs regularly for security policy changes
  3. **Tier Upgrades**: When upgrading tenants, inform them of new command permissions
  4. **Timeout Limits**: Set reasonable timeouts to prevent runaway commands
  5. **Command Validation**: Always validate command names (alphanumeric only)

Security Considerations

  1. **Command Injection**: Arguments are sanitized to prevent command injection
  2. **Privilege Escalation**: sudo and su always blacklisted (except enterprise)
  3. **Data Destruction**: rm, dd, mkfs always blacklisted (except enterprise)
  4. **Network Access**: curl, wget, rsync, ssh restricted by tier (available solo+)
  5. **Timeout Protection**: All commands timeout after configured duration

Future Enhancements

Potential improvements:

  • Command execution logging (which commands were run)
  • Per-agent security policies (more granular than tenant-level)
  • Time-based restrictions (limit command execution to business hours)
  • Resource limits (CPU, memory per command)
  • Command approval workflows (require admin approval for new commands)